#include "../global.h"

#include <vtkArrowSource.h>
#include <vtkTransform.h>
#include <time.h>
#include <vtkCellPicker.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    vtkCreate(arrowSource, vtkArrowSource);

    double startPoint[3], endPoint[3];
    vtkMath::RandomSeed(time(NULL));
    startPoint[0] = vtkMath::Random(-100,100);
    startPoint[1] = vtkMath::Random(-100,100);
    startPoint[2] = vtkMath::Random(-100,100);
    endPoint[0] = vtkMath::Random(-100,100);
    endPoint[1] = vtkMath::Random(-100,100);
    endPoint[2] = vtkMath::Random(-100,100);

    double normalizedX[3];
    double normalizedY[3];
    double normalizedZ[3];

    // The X axis is a vector from start to end
    vtkMath::Subtract(endPoint, startPoint, normalizedX);
    double length = vtkMath::Norm(normalizedX);
    vtkMath::Normalize(normalizedX);

    // The Z axis is an arbitrary vector cross X
    double arbitrary[3];
    arbitrary[0] = vtkMath::Random(-100,100);
    arbitrary[1] = vtkMath::Random(-100,100);
    arbitrary[2] = vtkMath::Random(-100,100);
    vtkMath::Cross(normalizedX, arbitrary, normalizedZ);
    vtkMath::Normalize(normalizedZ);

    // The Y axis is Z cross X
    vtkMath::Cross(normalizedZ, normalizedX, normalizedY);
    vtkCreate(matrix, vtkMatrix4x4);

    // Create the direction cosine matrix
    matrix->Identity();
    for (unsigned int i = 0; i < 3; i++)
    {
        matrix->SetElement(i, 0, normalizedX[i]);
        matrix->SetElement(i, 1, normalizedY[i]);
        matrix->SetElement(i, 2, normalizedZ[i]);
    }

    // Apply the transforms
    vtkCreate(transform, vtkTransform);
    transform->Translate(startPoint);
    transform->Concatenate(matrix);
    transform->Scale(length, length, length);

    //Create a mapper and actor for the arrow
    vtkCreate(mapper, vtkPolyDataMapper);
    vtkCreate(actor, vtkActor);

    mapper->SetInputConnection(arrowSource->GetOutputPort());
    actor->SetUserMatrix(transform->GetMatrix());
    actor->SetMapper(mapper);

    vtkCreate(reader, vtkDICOMImageReader);
    reader->SetDataByteOrderToLittleEndian();
    reader->SetDirectoryName(path.toStdString().c_str());
    reader->Update();

    vtkCreate(cubes, vtkMarchingCubes);
    cubes->SetInputConnection(reader->GetOutputPort());
    cubes->ComputeNormalsOn();
    cubes->SetValue(0, 250);

    vtkCreate(boneStripper, vtkStripper);
    boneStripper->SetInputConnection(cubes->GetOutputPort());

    vtkCreate(bi, vtkPolyDataNormals);
    bi->SetInputConnection(boneStripper->GetOutputPort());
    bi->SetComputeCellNormals(1);
    bi->SetComputePointNormals(1);
    bi->Update();

    vtkCreate(boneMapper, vtkPolyDataMapper);
    boneMapper->SetInputConnection(bi->GetOutputPort());

    vtkCreate(bone, vtkActor);
    bone->SetMapper(boneMapper);
    bone->GetProperty()->SetDiffuseColor(.1,.94,.52);
    bone->GetProperty()->SetSpecular(.3);
    bone->GetProperty()->SetSpecularPower(20);

    vtkCreate(renderer, vtkRenderer);
    vtkCreate(camera, vtkCamera);
    camera->SetViewUp(0,0,-1);
    camera->SetPosition(0,1,0);
    camera->SetFocalPoint(0,0,0);
    camera->Dolly(1.5);

    renderer->AddActor(bone);
    renderer->AddActor(actor);
    renderer->SetActiveCamera(camera);
    renderer->ResetCamera();
    renderer->SetBackground(0,0,0);
    renderer->ResetCameraClippingRange();

    vtkCreate(style, vtkInteractorStyleTrackballCamera);
    vtkWidgetCreate(widget, QVTKWidget);
    QVTKWidget* vtkWidget = widget.data();
    vtkWidget->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
    vtkWidget->GetRenderWindow()->AddRenderer(renderer);
    vtkWidget->resize(WINDOW_WIDTH, WINDOW_HEIGHT);
    vtkWidget->show();

    return a.exec();
}
